package com.example.demo.utils;

import fr.opensagres.poi.xwpf.converter.xhtml.Base64EmbedImgManager;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.HWPFDocumentCore;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.converter.WordToHtmlUtils;
import org.apache.poi.hwpf.model.PicturesTable;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.w3c.dom.Document;
import sun.misc.BASE64Encoder;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class Word2HtmlUtils {
    /**
     * 将docx类型的word文件转为html，其中图片直接以base64形式在文件中保存
     * @param file word文件
     * @return 生成的html文件路径
     * @throws IOException 异常处理
     */
    public String docx2html(File file) throws IOException {
        InputStream in =new FileInputStream(file);
        XWPFDocument docxDocument = new XWPFDocument(in);
        XHTMLOptions options = XHTMLOptions.create();
        //图片转base64
        options.setImageManager(new Base64EmbedImgManager());
        // 转换htm11
        ByteArrayOutputStream htmlStream = new ByteArrayOutputStream();
        XHTMLConverter.getInstance().convert(docxDocument, htmlStream, options);
        String htmlStr = htmlStream.toString();

        //tmp.html作为生产的Html文件的临时地址
        String targetFileName = this.getClass().getResource("/").getPath()+"static/html/tmp.html";
        writrString2File(htmlStr,targetFileName);
        return targetFileName;
    }

    /**
     * 将doc类型的word文件转为html，其中图片直接以base64形式存在文件中保存
     * @param file word文件
     * @return 生成的html文件路径
     */
    public String doc2html(File file) throws IOException, TransformerException, ParserConfigurationException {
        InputStream in =new FileInputStream(file);
        HWPFDocumentCore wordDocument = WordToHtmlUtils.loadDoc(in);
        org.w3c.dom.Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);
        // 直接将图片base64存在文件中
        wordToHtmlConverter.setPicturesManager(new PicturesManager() {
            public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches,
                                      float heightInches) {
                //return Base64.getEncoder().encodeToString(content);
                BASE64Encoder encoder=new BASE64Encoder();
                encoder.encode(content);
                return "data:;base64,"+encoder.encode(content);
            }
        });
        wordToHtmlConverter.processDocument(wordDocument);
        Document htmlDocument = wordToHtmlConverter.getDocument();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(out);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer serializer = transformerFactory.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);
        out.close();
        String htmlStr = new String(out.toByteArray());

        //tmp.html作为生产的Html文件的临时地址
        String targetFileName = this.getClass().getResource("/").getPath()+"static/html/tmp.html";
        writrString2File(htmlStr,targetFileName);
        return targetFileName;
    }

    /**
     * 将字符串写入文件
     * @param str 字符串
     * @param targetFileName 文件路径
     * @throws IOException 异常处理
     */
    private void writrString2File(String str, String targetFileName) throws IOException {
        FileWriter fw = null;
        File f = new File(targetFileName);
        if(!f.exists()){
            f.createNewFile();
        }
        fw = new FileWriter(f);
        BufferedWriter out = new BufferedWriter(fw);
        out.write(str, 0, str.length()-1);
        out.close();
    }

    /**
     * 提取docx文件中的文字
     * @param file word文件
     * @return 文件中的文字
     * @throws IOException 异常处理
     */
    public String collectTextFromDocx(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        XWPFDocument xdoc = new XWPFDocument(fis);
        XWPFWordExtractor extractor = new XWPFWordExtractor(xdoc);
        String result = extractor.getText();
        return result;
    }

    /**
     * 提取doc文件中的图片
     * @param file word文件
     * @return 图片列表
     * @throws IOException 异常处理
     */
    public ArrayList<File> collectPicsFromDocx(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        XWPFDocument xdoc = new XWPFDocument(fis);
        List<XWPFPictureData> pics=xdoc.getAllPictures();
        ArrayList<File> picList=new ArrayList<>();
        for(int i=0;i<pics.size();i++){
            if(i>=3) break;
            byte[] bytes = pics.get(i).getData();
            //一个临时的输出文件地址
            String tmpOutPath=this.getClass().getResource("/").getPath()+"static/image/"+pics.get(i).getFileName();
            OutputStream os = new FileOutputStream(tmpOutPath);
            java.io.File tmpFile=new java.io.File(tmpOutPath);

            int count = 0;
            while (bytes.length / 4096 > count) {
                os.write(bytes, 4096 * count++, 4096);
            }
            os.close();
            picList.add(tmpFile);
        }
        return picList;
    }

    public String collectTextFromDoc(File file) throws IOException {
        FileInputStream in=new FileInputStream(file);
        HWPFDocument doc = new HWPFDocument(in);

//        WordExtractor re = new WordExtractor(in);
//        re.getText();

        String result="";
         result = doc.getDocumentText();
         in.close();
        return result;
    }

    public ArrayList<File> collectPicsFromDoc(File file) throws IOException {
        FileInputStream in=new FileInputStream(file);
        HWPFDocument doc = new HWPFDocument(in);
        // 文档图片内容
        PicturesTable picturesTable = doc.getPicturesTable();
        List<Picture> pictures = picturesTable.getAllPictures();
        ArrayList<File> picList=new ArrayList<>();
        for (Picture picture : pictures) {
            // 输出图片到磁盘
            //一个临时的输出文件地址
            String tmpOutPath=this.getClass().getResource("/").getPath()+"static/image/"+ UUID.randomUUID() + "." + picture.suggestFileExtension();
            OutputStream out = new FileOutputStream(new File(tmpOutPath));
            picture.writeImageContent(out);
            out.close();
            java.io.File tmpFile=new java.io.File(tmpOutPath);
            picList.add(tmpFile);
        }
        return picList;
    }
}
